package com.gitee.wsl.android.ui.sample.icon

import android.animation.Animator

import android.animation.ValueAnimator

import android.animation.AnimatorListenerAdapter
import android.graphics.*
import android.view.animation.LinearInterpolator


/**
 * Created by codeest on 2016/11/14.
 *
 * 很Q 很弹 duang~ duang~ duang~
 */
class ENSearchView : AnimatedIcon() {
    private var mPaint: Paint? = null
    private var mArcPaint: Paint? = null
    private var mFraction = 0f
    private var mCurrentState = 0
    private var mPath: Path? = null
    private var mArcPath: Path? = null
    private var mPathMeasure: PathMeasure? = null
    private var mRectF: RectF? = null
    private var mWidth = 0f
    private var mHeight = 0f
    private var mCenterX = 0f
    private var mCenterY = 0f
    private var mPathLength = 0f
    private var mCircleRadius = 0f
    private lateinit var mCurrentPos: FloatArray
    private lateinit var mCurrentTan: FloatArray
    private var isDotShowing = true
    private var mDotSize = 0
    private var mDuration = 0

    /*constructor(context: Context?) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.search)
        val lineColor = ta.getColor(R.styleable.search_search_line_color, DEFAULT_LINE_COLOR)
        val lineWidth = ta.getInteger(R.styleable.search_search_line_width, DEFAULT_LINE_WIDTH)
        val dotSize = ta.getInteger(R.styleable.search_search_dot_size, DEFAULT_DOT_SIZE)
        ta.recycle()

    }*/

    init {
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mPaint!!.style = Paint.Style.STROKE
        mPaint!!.strokeCap = Paint.Cap.ROUND
        //mPaint!!.strokeWidth = lineWidth.toFloat()
        //mPaint!!.color = lineColor
        mArcPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mArcPaint!!.style = Paint.Style.FILL
        mArcPaint!!.color = Color.WHITE
        //mDotSize = dotSize
        mDuration = DEFAULT_DURATION
        mCurrentState = STATE_WAIT
        mCurrentPos = FloatArray(2)
        mCurrentTan = FloatArray(2)
        mPath = Path()
        mArcPath = Path()
        mPathMeasure = PathMeasure()
    }

    fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        mWidth = w.toFloat()
        mHeight = h.toFloat()
        mCenterX = mWidth / 2
        mCenterY = mHeight / 2
        mCircleRadius = mWidth / 4
        mRectF = RectF(
            mCenterX - 0.95f * mCircleRadius, mCenterY - 0.95f * mCircleRadius,
            mCenterX + 0.95f * mCircleRadius, mCenterY + 0.95f * mCircleRadius
        )
        mPath!!.moveTo(
            mCenterX + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(),
            mCenterY + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat()
        )
        mPath!!.lineTo(mCenterX, mCenterY)
        mPath!!.lineTo(
            mCenterX - 0.45f * mCircleRadius * Math.sqrt(3.0).toFloat(),
            mCenterY + 0.45f * mCircleRadius
        )
        mPath!!.lineTo(
            mCenterX - 0.45f * mCircleRadius * Math.sqrt(3.0).toFloat(),
            mCenterY - 0.45f * mCircleRadius
        )
        mPath!!.lineTo(mCenterX + 0.45f * mCircleRadius * Math.sqrt(3.0).toFloat(), mCenterY)
        mPath!!.lineTo(mCenterX, mCenterY)
        mPath!!.lineTo(
            mCenterX + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(),
            mCenterY + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat()
        )
        mPathMeasure!!.setPath(mPath, false)
        mPathLength = mPathMeasure!!.length
    }

    override fun startAnimation()  {
        start()
    }

     fun pause() {
        mCurrentState = STATE_WAIT
    }

    override fun draw(canvas: Canvas) {
        if (mFraction <= 0.2) { //嗷~ 放大镜手柄收缩
            canvas.drawCircle(
                mCenterX,
                mCenterY,
                mCircleRadius - mCircleRadius * mFraction,
                mPaint!!
            )
            canvas.drawLine(
                mCenterX + mCircleRadius / Math.sqrt(2.0)
                    .toFloat() + 1.2f * mCircleRadius / Math.sqrt(2.0).toFloat() / 0.2f * mFraction,
                mCenterY + mCircleRadius / Math.sqrt(2.0)
                    .toFloat() + 1.2f * mCircleRadius / Math.sqrt(2.0).toFloat() / 0.2f * mFraction,
                mCenterX + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(),
                mCenterY + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(), mPaint!!
            )
        } else if (mFraction <= 0.8) {
            mPathMeasure!!.getPosTan(
                0 + mPathLength / 0.6f * (mFraction - 0.2f),
                mCurrentPos,
                mCurrentTan
            )
            if (mCurrentPos[1] == mCenterY && mCurrentPos[0] <= mCenterX + mCircleRadius / 3 && mCurrentPos[0] >= mCenterX - mCircleRadius / 3) {
                isDotShowing = if (isDotShowing) {
                    false
                } else {
                    canvas.drawCircle(
                        mCurrentPos[0],
                        mCurrentPos[1],
                        mDotSize.toFloat(),
                        mPaint!!
                    ) //嗷~ 轨迹中的小球
                    true
                }
            } else {
                canvas.drawCircle(mCurrentPos[0], mCurrentPos[1], mDotSize.toFloat(), mPaint!!)
            }
            if (mFraction <= 0.3) { //嗷~ 内圈粘性部分
                canvas.drawCircle(
                    mCenterX,
                    mCenterY,
                    0.8f * mCircleRadius + mCircleRadius * 2 * (mFraction - 0.2f),
                    mPaint!!
                )
            } else {
                canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mPaint!!)
            }
            if (mFraction <= 0.35 && mFraction > 0.3) {
                canvas.drawArc(
                    mRectF!!,
                    45 - 55 / 0.05f * (mFraction - 0.3f),
                    110 / 0.05f * (mFraction - 0.3f),
                    false,
                    mArcPaint!!
                )
            } else if (mFraction <= 0.4 && mFraction > 0.35) {
                canvas.drawArc(
                    mRectF!!,
                    45 - 55 / 0.05f * (0.4f - mFraction),
                    110 / 0.05f * (0.4f - mFraction),
                    false,
                    mArcPaint!!
                )
            }
            if (mFraction <= 0.75 && mFraction > 0.7) {  //嗷~ 外圈粘性部分
                mArcPath!!.reset()
                mArcPath!!.moveTo(mCenterX + mCircleRadius, mCenterY)
                mArcPath!!.cubicTo(
                    mCenterX + mCircleRadius + 8 / 0.05f * (mFraction - 0.7f),
                    mCenterY + mCircleRadius / 2 + 8 / 0.05f * (mFraction - 0.7f),
                    mCenterX + mCircleRadius / 2 + 8 / 0.05f * (mFraction - 0.7f),
                    mCenterY + mCircleRadius + 8 / 0.05f * (mFraction - 0.7f),
                    mCenterX,
                    mCenterY + mCircleRadius
                )
                canvas.drawPath(mArcPath!!, mPaint!!)
            } else if (mFraction <= 0.8 && mFraction > 0.75) {
                mArcPath!!.reset()
                mArcPath!!.moveTo(mCenterX + mCircleRadius, mCenterY)
                mArcPath!!.cubicTo(
                    mCenterX + mCircleRadius + 8 / 0.05f * (0.8f - mFraction),
                    mCenterY + mCircleRadius / 2 + 8 / 0.05f * (0.8f - mFraction),
                    mCenterX + mCircleRadius / 2 + 8 / 0.05f * (0.8f - mFraction),
                    mCenterY + mCircleRadius + 8 / 0.05f * (0.8f - mFraction),
                    mCenterX,
                    mCenterY + mCircleRadius
                )
                canvas.drawPath(mArcPath!!, mPaint!!)
            }
        } else {    //嗷~ 放大镜手柄伸长
            canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mPaint!!)
            canvas.drawLine(
                mCenterX + 2.2f * mCircleRadius / Math.sqrt(2.0)
                    .toFloat() - 1.2f * mCircleRadius / Math.sqrt(2.0)
                    .toFloat() / 0.2f * (mFraction - 0.8f),
                mCenterY + 2.2f * mCircleRadius / Math.sqrt(2.0)
                    .toFloat() - 1.2f * mCircleRadius / Math.sqrt(2.0)
                    .toFloat() / 0.2f * (mFraction - 0.8f),
                mCenterX + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(),
                mCenterY + 2.2f * mCircleRadius / Math.sqrt(2.0).toFloat(), mPaint!!
            )
        }
    }

    fun start() {
        if (mCurrentState == STATE_SEARCHING) {
            return
        }
        mCurrentState = STATE_SEARCHING
        val valueAnim = ValueAnimator.ofFloat(1f, 100f)
        valueAnim.duration = mDuration.toLong()
        valueAnim.interpolator = LinearInterpolator()
        valueAnim.addUpdateListener { valueAnimator ->
            mFraction = valueAnimator.animatedFraction
            invalidateSelf()
        }
        valueAnim.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                mCurrentState = STATE_WAIT
            }
        })
        valueAnim.start()
    }

    companion object {
        private const val STATE_SEARCHING = 0
        private const val STATE_WAIT = 1
        private const val DEFAULT_LINE_COLOR = Color.WHITE
        private const val DEFAULT_LINE_WIDTH = 9
        private const val DEFAULT_DOT_SIZE = 3
        private const val DEFAULT_DURATION = 3000
    }
}